/*
    Copyright 2006-2011 Patrik Jonsson, sunrise@familjenjonsson.org

    This file is part of Sunrise.

    Sunrise is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    Sunrise is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Sunrise.  If not, see <http://www.gnu.org/licenses/>.

*/

/// \file
/// Contains the unit_map class used to keep units.

// $Id$

#ifndef __mcrx_units__
#define __mcrx_units__

#include <map> 
#include <string> 
#include <iostream>
#include "units.h"

namespace mcrx{
  /** The unit_map class is used to keep track of which sets of units
      different parts of the code are using. It's just a map with some
      added functionality that makes it easier to get units and check
      that unit sets are consistent. */
  class unit_map : public std::map<std::string,std::string> {
  public:
    unit_map() : std::map<std::string,std::string>() {};
    virtual ~unit_map() {};

    class undefined {};

    std::string get(const std::string qty) const {
      const_iterator i = find(qty);
      if (i!=end()) {
	return i->second;
      }
      std::cerr << "No unit defined for " << qty << std::endl;
      dump();
      std::cerr.flush();
      throw undefined();
    };

    void dump() const {
      std::cout << "Units: \n";
      for(const_iterator i=begin(); i!= end();++i)
	std::cout << i->first << ":\t" << i->second << "\n";
    };

  };
    
  /** This typedef is what classes actually use to keep track of
      units, because it used to just be a typedef to the plain map. */
  typedef unit_map T_unit_map;

  /// Checks that all units that are defined in both maps are consistent.
  bool check_consistency (const T_unit_map& a, const T_unit_map& b, 
			  bool exit_on_fail = false);
}

#endif

